"""
文件上传服务
"""
import asyncio
import logging
from typing import List, Dict, Any
import httpx
from fastapi import UploadFile

from app.core.config import settings

logger = logging.getLogger(__name__)


class FileUploadService:
    """文件上传服务类"""
    
    def __init__(self):
        self.upload_url = settings.UPLOAD_URL
        self.headers = {
            "Authorization": settings.AUTH_TOKEN
        }
        self.timeout = httpx.Timeout(settings.REQUEST_TIMEOUT)
    
    async def upload_single_file(self, file: UploadFile) -> Dict[str, Any]:
        """
        上传单个文件到远程服务器
        
        Args:
            file: FastAPI的UploadFile对象
            
        Returns:
            包含file_id和原始文件名的字典
            
        Raises:
            Exception: 上传失败时抛出异常
        """
        try:
            # 读取文件内容
            file_content = await file.read()
            file_name = file.filename or "unknown"
            
            logger.info(f"开始上传文件: {file_name}, 大小: {len(file_content)} 字节")
            
            # 准备multipart/form-data格式的文件
            files = {
                "file": (file_name, file_content, file.content_type or "application/octet-stream")
            }
            
            # 发送POST请求
            async with httpx.AsyncClient(timeout=self.timeout) as client:
                response = await client.post(
                    self.upload_url,
                    headers=self.headers,
                    files=files
                )
                response.raise_for_status()
                
                result = response.json()
                
                # 验证返回数据
                if result.get("code") == 1 and "data" in result:
                    file_id = result["data"]
                    logger.info(f"文件上传成功: {file_name}, ID: {file_id}")
                    return {
                        "file_id": file_id,
                        "filename": file_name,
                        "success": True
                    }
                else:
                    raise Exception(f"上传失败: {result.get('msg', '未知错误')}")
                    
        except httpx.HTTPStatusError as e:
            logger.error(f"HTTP错误: {e.response.status_code} - {e.response.text}")
            raise Exception(f"文件上传HTTP错误: {e.response.status_code}")
        except Exception as e:
            logger.error(f"文件上传失败: {str(e)}")
            raise Exception(f"文件上传失败: {str(e)}")
        finally:
            # 重置文件指针
            await file.seek(0)
    
    async def upload_multiple_files(self, files: List[UploadFile]) -> List[Dict[str, Any]]:
        """
        批量上传多个文件
        
        Args:
            files: UploadFile列表
            
        Returns:
            上传结果列表
        """
        if not files:
            return []
        
        logger.info(f"开始批量上传 {len(files)} 个文件")
        
        # 并发上传所有文件
        tasks = [self.upload_single_file(file) for file in files]
        results = await asyncio.gather(*tasks, return_exceptions=True)
        
        # 处理结果
        upload_results = []
        for idx, result in enumerate(results):
            if isinstance(result, Exception):
                logger.error(f"文件 {idx} 上传失败: {str(result)}")
                upload_results.append({
                    "filename": files[idx].filename if idx < len(files) else "unknown",
                    "success": False,
                    "error": str(result)
                })
            else:
                upload_results.append(result)
        
        success_count = sum(1 for r in upload_results if r.get("success"))
        logger.info(f"批量上传完成: 成功 {success_count}/{len(files)}")
        
        return upload_results
    
    def get_file_ids_for_agent(self, upload_results: List[Dict[str, Any]]) -> List[Dict[str, str]]:
        """
        从上传结果中提取文件ID，格式化为智能体接口所需的格式
        
        Args:
            upload_results: 上传结果列表
            
        Returns:
            格式化的文件ID列表 [{"fileId": "xxx"}, ...]
        """
        file_ids = []
        for result in upload_results:
            if result.get("success") and "file_id" in result:
                file_ids.append({"fileId": result["file_id"]})
        
        logger.info(f"提取到 {len(file_ids)} 个有效文件ID")
        return file_ids

